package cn.caplike.demo.repository.design.pattern.combined.annotation;

import cn.caplike.demo.repository.design.pattern.combined.annotation.definition.FinanceType;
import cn.caplike.demo.repository.design.pattern.combined.annotation.definition.FinanceVersion;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@SuppressWarnings("unused")
public class ApiCache {

    /**
     * Description: 获取配置缓存
     *
     * @param key {@link Key} 缓存的 Key
     * @return java.lang.String
     * @throws RuntimeException 当不存在指定 Key 的缓存时
     * @author LiKe
     * @date 2019-11-02 16:14:29
     */
    public static String get(ApiCache.Key key) {
        final String cacheValue = getInstance().get(key.definition);
        if (StringUtils.isBlank(cacheValue)) {
            throw new RuntimeException(String.format("缓存中不存在 %s", key.definition));
        }
        return cacheValue;
    }

    /**
     * Description: 获取单例缓存实例
     *
     * @return java.util.Map
     * @author LiKe
     * @date 2019-11-02 15:40:06
     */
    private static Map<String, String> getInstance() {
        return SingletonHolder.map;
    }

    /**
     * Description: 核心配置缓存 Key 定义
     *
     * @author LiKe
     * @date 2019-11-02 15:33:09
     */
    public enum Key {

        /**
         * 财务接口类型
         */
        FINANCE_TYPE("[FINANCE_TYPE]"),

        /**
         * 财务接口版本
         */
        FINANCE_VERSION("[FINANCE_VERSION]");

        private final String definition;

        Key(String definition) {
            this.definition = definition;
        }
    }

    /**
     * Description: 构建器
     *
     * @author LiKe
     * @date 2019-11-02 15:23:31
     */
    public static class Builder {

        /**
         * Description: 初始化构建器
         *
         * @return {@link Builder}
         * @author LiKe
         * @date 2019-11-02 15:31:30
         */
        public static Builder of() {
            return new Builder();
        }

        /**
         * Description: 缓存财务接口类型
         *
         * @param financeType 财务接口类型
         * @return {@link Builder}
         * @author LiKe
         * @date 2019-11-02 15:49:06
         */
        public Builder financeType(FinanceType financeType) {
            ApiCache.getInstance().put(Key.FINANCE_TYPE.definition, financeType.name());
            return this;
        }

        /**
         * Description: 缓存财务接口版本
         *
         * @param financeVersion 财务接口版本
         * @return {@link Builder}
         * @author LiKe
         * @date 2019-11-02 15:49:42
         */
        public Builder financeVersion(FinanceVersion financeVersion) {
            ApiCache.getInstance().put(Key.FINANCE_VERSION.definition, financeVersion.getVersion());
            return this;
        }
    }

    /**
     * Description: 单例 Holder
     *
     * @author LiKe
     * @date 2019-11-02 11:39:41
     */
    private static class SingletonHolder {
        private static final ConcurrentHashMap<String, String> map = initialize();

        private static ConcurrentHashMap<String, String> initialize() {
            if (Objects.isNull(map))
                return new ConcurrentHashMap<>();
            return map;
        }
    }
}
